package com.aiyige.page.my.download;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.aiyige.R;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.BaseActivity;
import com.aiyige.base.db.dao.DownloadFileDao;
import com.aiyige.base.db.dao.DownloadModelDao;
import com.aiyige.base.db.table.DownloadFile;
import com.aiyige.base.db.table.DownloadModel;
import com.aiyige.page.my.download.adapter.DownloadModelAdapter;
import com.aiyige.page.my.download.util.DownloadUtil;
import com.aiyige.track.TrackEvent;
import com.aiyige.track.annotation.Track;
import com.aiyige.utils.AccountUtil;
import com.aiyige.utils.HighLightWordUtil;
import com.aiyige.utils.TextWatcherAdapter;
import com.aiyige.utils.widget.CommonBottomDialogFragment;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.j256.ormlite.stmt.Where;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import timber.log.Timber;

@Track("我的缓存")
@Route(path = ARouterConfig.DownloadPage, extras = ARouterConfig.EXTRA_NEED_LOGIN)
public class DownloadPage extends BaseActivity {
    public static final String TAG = DownloadPage.class.getSimpleName();
    public static final int FILTER_TYPE_ALL = 1;
    public static final int FILTER_TYPE_LEARN_VIDEO = 2;
    public static final int FILTER_TYPE_NORMAL_VIDEO = 3;
    public static final int HANDLE_SEARCH = 1;
    @BindView(R.id.titleTv)
    TextView titleTv;
    @BindView(R.id.titleActionBtn)
    Button titleActionBtn;
    @BindView(R.id.searchIcon)
    ImageView searchIcon;
    @BindView(R.id.inputEt)
    EditText inputEt;
    @BindView(R.id.searchLayout)
    LinearLayout searchLayout;
    @BindView(R.id.filterBtn)
    ImageView filterBtn;
    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;
    boolean edit;
    @BindView(R.id.editLayout)
    ViewGroup editLayout;
    DownloadModelAdapter downloadModelAdapter;
    Lock mutex;
    CommonBottomDialogFragment filterDialog;
    int filterType = FILTER_TYPE_ALL;
    BroadcastReceiver broadcastReceiver;
    @BindView(R.id.searchResultRv)
    RecyclerView searchResultRv;
    @BindView(R.id.searchResultLayout)
    FrameLayout searchResultLayout;
    @BindView(R.id.selectAllIv)
    ImageView selectAllIv;
    DownloadModelAdapter searchAdapter;

    Handler mainHandler;
    Handler searchHandler;
    HandlerThread searchThread;
    TrackEvent trackEvent = new TrackEvent();
    @BindView(R.id.inputEtClearBtn)
    ImageView inputEtClearBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        edit = false;
        mutex = new ReentrantLock();
        filterType = FILTER_TYPE_ALL;
        setContentView(R.layout.page_download);
        ButterKnife.bind(this);
        ARouter.getInstance().inject(this);


        inputEt.addTextChangedListener(new TextWatcherAdapter() {
            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() == 0) {
                    hideSearch();
                }
            }
        });

        inputEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                inputEtClearBtn.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
            }
        });
        inputEt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                    doSearch(inputEt.getText().toString());
                    return false;
                }
                return true;
            }
        });
        titleTv.setText(R.string.my_download);
        updateTitleActionBtn();
        updateEditLayout();
        downloadModelAdapter = new DownloadModelAdapter(this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setItemAnimator(null);
        downloadModelAdapter.bindToRecyclerView(recyclerView);
        downloadModelAdapter.setEmptyView(R.layout.standard_empty_layout);
        downloadModelAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                if (!edit) {
                    DownloadModel downloadModel = downloadModelAdapter.getItem(position);
                    ARouter.getInstance()
                            .build(ARouterConfig.DownloadDetailPage)
                            .withString("title", downloadModel.getTitle())
                            .withInt("parentType", downloadModel.getModelType())
                            .withString("parentId", downloadModel.getId())
                            .navigation();
                } else {
                    DownloadModel downloadModel = downloadModelAdapter.getItem(position);
                    downloadModel.setSelected(!downloadModel.isSelected());
                    downloadModelAdapter.setData(position, downloadModel);
                    updateSelectAllIv();
                }
            }
        });
//        downloadModelAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
//            @Override
//            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
//                switch (view.getId()) {
//                    case R.id.selectLayout:
//                        DownloadModel downloadModel = downloadModelAdapter.getItem(position);
//                        downloadModel.setSelected(!downloadModel.isSelected());
//                        downloadModelAdapter.setData(position, downloadModel);
//                        updateSelectAllIv();
//                        break;
//                }
//            }
//        });
        searchResultRv.setLayoutManager(new LinearLayoutManager(this));
        searchResultRv.setItemAnimator(null);
        searchAdapter = new DownloadModelAdapter(this);
        searchAdapter.bindToRecyclerView(searchResultRv);
        searchAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                DownloadModel downloadModel = searchAdapter.getItem(position);
                ARouter.getInstance()
                        .build(ARouterConfig.DownloadDetailPage)
                        .withString("title", downloadModel.getTitle())
                        .withInt("parentType", downloadModel.getModelType())
                        .withString("parentId", downloadModel.getId())
                        .navigation();
            }
        });
        searchAdapter.setEmptyView(R.layout.standard_search_empty_layout);
        filterDialog = CommonBottomDialogFragment.newBuilder()
                .layoutResId(R.layout.download_page_filter_dialog)
                .viewIdList(R.id.cancelBtn, R.id.allBtn, R.id.normalVideoBtn, R.id.learnVideoBtn)
                .listener(new CommonBottomDialogFragment.Listener() {
                    @Override
                    public void onViewClicked(int position, View view) {
                        mutex.lock();
                        switch (view.getId()) {
                            case R.id.allBtn:
                                filterType = FILTER_TYPE_ALL;
                                break;
                            case R.id.normalVideoBtn:
                                filterType = FILTER_TYPE_NORMAL_VIDEO;
                                break;
                            case R.id.learnVideoBtn:
                                filterType = FILTER_TYPE_LEARN_VIDEO;
                                break;
                        }
                        mutex.unlock();
                        query();
                    }
                })
                .build();
        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                try {
                    String action = intent.getAction();
                    switch (action) {
                        case DownloadUtil.ACTION_DOWNLOAD_PROGRESS_STATUS_UPDATE:
                            query();
                            break;
                    }

                } catch (Exception e) {

                }
            }
        };
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(DownloadUtil.ACTION_DOWNLOAD_PROGRESS_STATUS_UPDATE);
        registerReceiver(broadcastReceiver, intentFilter);


        mainHandler = new Handler(Looper.getMainLooper());
        searchThread = new HandlerThread(TAG + "SearchThread");
        searchThread.start();
        searchHandler = new Handler(searchThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case HANDLE_SEARCH:
                        String searchStr = (String) msg.obj;
                        final List<DownloadModel> resultList = new LinkedList<>();
                        if (!TextUtils.isEmpty(searchStr)) {
                            try {
                                QueryBuilder<DownloadModel, String> queryBuilder = DownloadModelDao.getDao().queryBuilder();
                                Where<DownloadModel, String> where = queryBuilder.where();
                                where.and(
                                        where.eq(DownloadModel.USER_ID_FIELD, AccountUtil.getCurrentUser().getId())
                                                .and()
                                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                                .and()
                                                .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                        ,
                                        where.like(DownloadModel.AUTHOR_NAME_FIELD, "%" + searchStr + "%")
                                                .or()
                                                .like(DownloadModel.TITLE_FIELD, "%" + searchStr + "%")
                                );
                                resultList.addAll(queryBuilder.query());
                                for (DownloadModel downloadModel : resultList) {
                                    downloadModel.setTitle(HighLightWordUtil.highLight(downloadModel.getTitle(), searchStr));
                                    downloadModel.setAuthorName(HighLightWordUtil.highLight(downloadModel.getAuthorName(), searchStr));
                                    try {
                                        List<DownloadFile> downloadFileList = DownloadFileDao.getDao().queryBuilder()
                                                .where()
                                                .eq(DownloadFile.PARENT_ID_FIELD, downloadModel.getId())
                                                .and()
                                                .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                                .and()
                                                .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                                .query();
                                        long totalDuration = 0;
                                        for (DownloadFile downloadFile : downloadFileList) {
                                            totalDuration += downloadFile.getDuration();
                                        }
                                        downloadModel.setTotalDuration(totalDuration);
                                    } catch (SQLException e) {
                                        Timber.e("doInBackground:" + Log.getStackTraceString(e));
                                    }
                                }
                            } catch (Exception e) {
                                Timber.e("handleMessage:" + Log.getStackTraceString(e));
                            }
                        }
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                showSearch();
                                searchAdapter.setNewData(resultList);
                            }
                        });
                        break;
                }
            }
        };
        DownloadUtil.startDownload();
    }

    @Override
    protected void onResume() {
        super.onResume();
        query();
    }

    @Override
    protected void onDestroy() {
        searchThread.quit();
        try {
            unregisterReceiver(broadcastReceiver);
        } catch (Exception e) {

        }
        super.onDestroy();
    }

    public void doSearch(String searchStr) {
        if (TextUtils.isEmpty(searchStr)) return;
        Message msg = Message.obtain();
        msg.what = HANDLE_SEARCH;
        msg.obj = searchStr;
        searchHandler.removeMessages(HANDLE_SEARCH);
        searchHandler.sendMessage(msg);
    }

    public void query() {
        new AsyncTask<Object, Object, List<DownloadModel>>() {
            @Override
            protected List<DownloadModel> doInBackground(Object... objects) {
                mutex.lock();
                DownloadUtil.scanDownload();
                List<DownloadModel> downloadModelList = new LinkedList<>();
                try {
                    switch (filterType) {
                        case FILTER_TYPE_ALL:
                            downloadModelList.addAll(DownloadModelDao.getDao().queryBuilder()
                                    .orderBy(DownloadModel.DOWNLOAD_DATE_FIELD, false)
                                    .where()
                                    .eq(DownloadModel.USER_ID_FIELD, AccountUtil.getCurrentUser().getId())
                                    .and()
                                    .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                    .and()
                                    .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                    .query());
                            break;
                        case FILTER_TYPE_LEARN_VIDEO:
                            downloadModelList.addAll(DownloadModelDao.getDao().queryBuilder()
                                    .orderBy(DownloadModel.DOWNLOAD_DATE_FIELD, false)
                                    .where()
                                    .eq(DownloadModel.USER_ID_FIELD, AccountUtil.getCurrentUser().getId())
                                    .and()
                                    .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                    .and()
                                    .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                    .and()
                                    .eq(DownloadModel.MODEL_TYPE_FIELD, DownloadUtil.MODEL_TYPE_LEARN_VIDEO)
                                    .query());
                            break;
                        case FILTER_TYPE_NORMAL_VIDEO:
                            downloadModelList.addAll(DownloadModelDao.getDao().queryBuilder()
                                    .orderBy(DownloadModel.DOWNLOAD_DATE_FIELD, false)
                                    .where()
                                    .eq(DownloadModel.USER_ID_FIELD, AccountUtil.getCurrentUser().getId())
                                    .and()
                                    .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                    .and()
                                    .ne(DownloadModel.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                    .and()
                                    .eq(DownloadModel.MODEL_TYPE_FIELD, DownloadUtil.MODEL_TYPE_NORMAL_VIDEO)
                                    .query());
                            break;
                    }


                } catch (Exception e) {

                }
                for (DownloadModel downloadModel : downloadModelList) {
                    downloadModel.setEdit(edit);
                }
                if (edit) {
                    List<DownloadModel> oldList = downloadModelAdapter.getData();
                    outerLoop:
                    for (DownloadModel oldModel : oldList) {
                        for (DownloadModel newModel : downloadModelList) {
                            if (oldModel.getId().equals(newModel.getId())) {
                                newModel.setSelected(oldModel.isSelected());
                                continue outerLoop;
                            }
                        }
                    }
                }
                mutex.unlock();
                for (DownloadModel downloadModel : downloadModelList) {
                    try {
                        List<DownloadFile> downloadFileList = DownloadFileDao.getDao().queryBuilder()
                                .where()
                                .eq(DownloadFile.PARENT_ID_FIELD, downloadModel.getId())
                                .and()
                                .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE)
                                .and()
                                .ne(DownloadFile.CONTROL_OPTION_FIELD, DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY)
                                .query();
                        long totalDuration = 0;
                        for (DownloadFile downloadFile : downloadFileList) {
                            totalDuration += downloadFile.getDuration();
                        }
                        downloadModel.setTotalDuration(totalDuration);
                    } catch (SQLException e) {
                        Timber.e("doInBackground:" + Log.getStackTraceString(e));
                    }
                }
                {
                    int normalVideoNum = 0;
                    int learnVideoNum = 0;
                    for (DownloadModel item : downloadModelList) {
                        if (item.getProgressStatus() != DownloadUtil.PROGRESS_STATUS_DOWNLOAD_FINISHED)
                            continue;
                        switch (item.getModelType()) {
                            case DownloadUtil.MODEL_TYPE_NORMAL_VIDEO:
                                normalVideoNum++;
                                break;
                            case DownloadUtil.MODEL_TYPE_LEARN_VIDEO:
                                learnVideoNum++;
                                break;
                        }
                    }
                    Map<String, String> attrs = new HashMap<>();
                    attrs.put("video_num", String.valueOf(normalVideoNum));
                    attrs.put("learn_video_num", String.valueOf(learnVideoNum));
                    attrs.put("total_num", String.valueOf(normalVideoNum + learnVideoNum));
                    trackEvent.sendEvent(DownloadPage.this, TrackEvent.MY_CACHE_FINISH_NUM, TrackEvent.MY_CACHE_FINISH_NUM_LABEL, attrs, true);
                }
                {
                    int normalVideoNum = 0;
                    int learnVideoNum = 0;
                    for (DownloadModel item : downloadModelList) {
                        if (item.getControlOption() != DownloadUtil.CONTROL_OPTION_PAUSE)
                            continue;
                        switch (item.getModelType()) {
                            case DownloadUtil.MODEL_TYPE_NORMAL_VIDEO:
                                normalVideoNum++;
                                break;
                            case DownloadUtil.MODEL_TYPE_LEARN_VIDEO:
                                learnVideoNum++;
                                break;
                        }
                    }
                    Map<String, String> attrs = new HashMap<>();
                    attrs.put("video_num", String.valueOf(normalVideoNum));
                    attrs.put("learn_video_num", String.valueOf(learnVideoNum));
                    attrs.put("total_num", String.valueOf(normalVideoNum + learnVideoNum));
                    trackEvent.sendEvent(DownloadPage.this, TrackEvent.MY_CACHE_PAUSE_NUM, TrackEvent.MY_CACHE_PAUSE_NUM_LABEL, attrs, true);
                }
                return downloadModelList;
            }

            @Override
            protected void onPostExecute(List<DownloadModel> list) {
                downloadModelAdapter.setNewData(list);
                updateSelectAllIv();
            }
        }.execute();
    }

    public void updateTitleActionBtn() {
        titleActionBtn.setText(edit ? R.string.cancel : R.string.edit);
    }

    @OnClick({R.id.inputEtClearBtn, R.id.selectAllBtn, R.id.deleteBtn, R.id.titleBackBtn, R.id.titleActionBtn, R.id.filterBtn})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.inputEtClearBtn:
                inputEt.setText("");
                break;
            case R.id.titleBackBtn:
                finish();
                break;
            case R.id.titleActionBtn: {
                mutex.lock();
                edit = !edit;
                updateTitleActionBtn();
                updateEditLayout();
                updateEditState();
                updateSelectAllIv();
                mutex.unlock();
                break;
            }
            case R.id.filterBtn:
                filterDialog.show(getSupportFragmentManager(), "");
                break;
            case R.id.selectAllBtn:
                mutex.lock();
                if (!checkAllSelected()) {
                    doSelectAll();
                } else {
                    unSelectAll();
                }
                updateSelectAllIv();
                mutex.unlock();
                break;
            case R.id.deleteBtn:
                mutex.lock();
                for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
                    if (downloadModel.isSelected()) {
                        try {
                            UpdateBuilder<DownloadModel, String> updateBuilder = DownloadModelDao.getDao().updateBuilder();
                            updateBuilder.updateColumnValue(DownloadModel.CONTROL_OPTION_FIELD, downloadModel.getModelType() != DownloadUtil.MODEL_TYPE_LOCAL_VIDEO ? DownloadUtil.CONTROL_OPTION_DELETE : DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY);
                            updateBuilder.where().eq(DownloadModel.ID_FIELD, downloadModel.getId());
                            updateBuilder.update();
                            if (downloadModel.getProgressStatus() != DownloadUtil.PROGRESS_STATUS_DOWNLOAD_FINISHED) {
                                Map<String, String> attrs = new HashMap<>();
                                switch (downloadModel.getModelType()) {
                                    case DownloadUtil.MODEL_TYPE_LEARN_VIDEO:
                                        attrs.put("type", "0");
                                        break;
                                    case DownloadUtil.MODEL_TYPE_NORMAL_VIDEO:
                                        attrs.put("type", "1");
                                        break;
                                }
                                trackEvent.sendEvent(this, TrackEvent.DELETE_MY_UNFINISH_CACHE, TrackEvent.DELETE_MY_UNFINISH_CACHE_LABEL, attrs);
                            }
                        } catch (Exception e) {
                            Timber.e("onViewClicked:" + Log.getStackTraceString(e));
                        }
                        try {
                            List<DownloadFile> downloadFileList = DownloadFileDao.getDao().queryBuilder()
                                    .where()
                                    .eq(DownloadFile.PARENT_ID_FIELD, downloadModel.getId())
                                    .query();
                            for (DownloadFile downloadFile : downloadFileList) {
                                UpdateBuilder<DownloadFile, Integer> updateBuilder = DownloadFileDao.getDao().updateBuilder();
                                updateBuilder.updateColumnValue(DownloadModel.CONTROL_OPTION_FIELD, downloadModel.getModelType() != DownloadUtil.MODEL_TYPE_LOCAL_VIDEO ? DownloadUtil.CONTROL_OPTION_DELETE : DownloadUtil.CONTROL_OPTION_DELETE_RECORD_ONLY);
                                updateBuilder.where().eq(DownloadFile.ID_FIELD, downloadFile.getId());
                                updateBuilder.update();
                            }
                        } catch (Exception e) {
                            Timber.e("onViewClicked:" + Log.getStackTraceString(e));
                        }


                    }
                }
                mutex.unlock();
                query();
                break;
        }
    }

    public void updateEditLayout() {
        if (edit) {
            editLayout.setVisibility(View.VISIBLE);
        } else {
            editLayout.setVisibility(View.GONE);
        }
    }

    public void updateEditState() {

        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            downloadModel.setEdit(edit);
        }
        downloadModelAdapter.notifyDataSetChanged();

    }

    public void doSelectAll() {
        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            downloadModel.setSelected(true);
        }
        downloadModelAdapter.notifyDataSetChanged();
    }

    public void unSelectAll() {
        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            downloadModel.setSelected(false);
        }
        downloadModelAdapter.notifyDataSetChanged();
    }


    public void showSearch() {
        searchResultLayout.setVisibility(View.VISIBLE);
    }

    public void hideSearch() {
        searchAdapter.setNewData(null);
        searchResultLayout.setVisibility(View.INVISIBLE);
    }

    public boolean checkAllSelected() {
        boolean result = true;
        for (DownloadModel downloadModel : downloadModelAdapter.getData()) {
            if (!downloadModel.isSelected()) {
                result = false;
                break;
            }
        }
        return result;
    }


    public void updateSelectAllIv() {
        if (checkAllSelected()) {
            selectAllIv.setImageResource(R.drawable.order_screen_selected);
        } else {
            selectAllIv.setImageResource(R.drawable.order_screen_normal);
        }
    }

}
